<?php
/* -------------------------------------------------------------------------------------
* 	ID:						$Id: class.cart.php 319 2013-09-26 19:49:55Z phone.mueller@googlemail.com $
* 	Letzter Stand:			$Revision: 319 $
* 	zuletzt geaendert von:	$Author: siekiera $
* 	Datum:					$Date: 2013-09-26 19:49:55 +0000 (Thu, 26 Sep 2013) $
*
* 	SEO:mercari by Siekiera Media
* 	http://www.seo-mercari.de
*
* 	Copyright (c) since 2011 SEO:mercari
* --------------------------------------------------------------------------------------
* 	based on:
* 	(c) 2000-2001 The Exchange Project  (earlier name of osCommerce)
* 	(c) 2002-2003 osCommerce - www.oscommerce.com
* 	(c) 2003     nextcommerce - www.nextcommerce.org
* 	(c) 2005     xt:Commerce - www.xt-commerce.com
*
* 	Released under the GNU General Public License
* ----------------------------------------------------------------------------------- */

require_once (DIR_FS_INC.'inc.create_random_value.php');
require_once (DIR_FS_INC.'inc.array_get_item.php');
require_once (DIR_FS_INC.'inc.get_prid.php');
require_once (DIR_FS_INC.'inc.draw_form.php');
require_once (DIR_FS_INC.'inc.draw_input_field.php');
require_once (DIR_FS_INC.'inc.image_submit.php');
require_once (DIR_FS_INC.'inc.get_tax_description.php');

class cart {
	var $contents, $products, $total, $weight, $cartID, $content_type;

	public function __construct() {
		$this->reset();
	}

	public function restore_contents() {
		global $db;
		if(!isset($_SESSION['customer_id']))
			return false;
		if(is_array($this->contents)) {
			reset($this->contents);
			while(list($products_id,) = each($this->contents)) {
				$qty = $this->contents[$products_id]['qty'];
				$product = $db->db_query("SELECT products_id FROM ".TABLE_CUSTOMERS_BASKET." WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."'");
				if($product->_numOfRows <= 0) {
					$db->db_query("INSERT INTO ".TABLE_CUSTOMERS_BASKET." (customers_id, products_id, customers_basket_quantity, customers_basket_date_added) VALUES ('".$_SESSION['customer_id']."', '".$products_id."', '".$qty."', '".date('Ymd')."')");
					if(isset($this->contents[$products_id]['attributes'])) {
						reset($this->contents[$products_id]['attributes']);
						while(list ($option, $value) = each($this->contents[$products_id]['attributes'])) {
							$db->db_query("INSERT INTO ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." (customers_id, products_id, products_options_id, products_options_value_id) VALUES ('".$_SESSION['customer_id']."', '".$products_id."', '".$option."', '".$value."')");
						}
					}
				} else
					$db->db_query("UPDATE ".TABLE_CUSTOMERS_BASKET." SET customers_basket_quantity = '".$qty."' WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."'");
			}
		}

		// reset per-session cart contents, but not the database contents
		$this->reset(false);

		$products = $db->db_query("SELECT products_id, customers_basket_quantity FROM ".TABLE_CUSTOMERS_BASKET." WHERE customers_id = '".$_SESSION['customer_id']."'");
		while(!$products->EOF) {
			$this->contents[$products->fields['products_id']] = array ('qty' => $products->fields['customers_basket_quantity']);
			$attributes = $db->db_query("SELECT
											cpa.products_options_id, cpa.products_options_value_id
										FROM
											".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." cpa
										WHERE
											customers_id = '".$_SESSION['customer_id']."'
										AND
											products_id = '".$products->fields['products_id']."'");
			while(!$attributes->EOF) { 
  				$this->contents[$products->fields['products_id']]['attributes'][$attributes->fields['products_options_id']] = $attributes->fields['products_options_value_id'];
				$attributes->MoveNext();
			}
			$products->MoveNext();
		}
		$this->cleanup();
	}

	public function reset($reset_database = false) {
		global $db;
		$this->contents = array ();
		$this->total = 0;
		$this->tax = 0;
		$this->weight = 0;
		$this->content_type = false;

		if(isset($_SESSION['customer_id']) && ($reset_database == true)) {
			$db->db_query("DELETE FROM ".TABLE_CUSTOMERS_BASKET." WHERE customers_id = '".$_SESSION['customer_id']."'");
			$db->db_query("DELETE FROM ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." WHERE customers_id = '".$_SESSION['customer_id']."'");
		}

		unset ($this->cartID);
		if (isset ($_SESSION['cartID']))
			unset ($_SESSION['cartID']);
	}

	public function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
		global $new_products_id_in_cart, $db;

		$products_id = get_uprid($products_id, $attributes);
		if($notify == true)
			$_SESSION['new_products_id_in_cart'] = $products_id;

		if($this->in_cart($products_id))
			$this->update_quantity($products_id, $qty, $attributes);
    else {
  			$this->contents[] = array($products_id);
			$this->contents[$products_id] = array('qty' => $qty);

			if(isset($_SESSION['customer_id']))
				$db->db_query("INSERT INTO
									".TABLE_CUSTOMERS_BASKET." (customers_id, products_id, customers_basket_quantity, customers_basket_date_added)
								VALUES
									('".$_SESSION['customer_id']."', '".$products_id."', '".$qty."', '".date('Ymd')."')");

			if(is_array($attributes)) {
				reset($attributes);
				while(list($option, $value) = each($attributes)) {
					$this->contents[$products_id]['attributes'][$option] = $value;
					if (isset ($_SESSION['customer_id']))
						$db->db_query("INSERT INTO
											".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." (customers_id, products_id, products_options_id, products_options_value_id)
										VALUES
											('".$_SESSION['customer_id']."', '".$products_id."', '".$option."', '".$value."')");
				}
			}
		}
		$this->cleanup();

		$this->cartID = $this->generate_cart_id();
	}

	public function update_quantity($products_id, $quantity = '', $attributes = '') {
		global $db;

		if(empty($quantity))
			return true;

		$this->contents[$products_id] = array ('qty' => $quantity);

		if(isset($_SESSION['customer_id']))
			$db->db_query("UPDATE ".TABLE_CUSTOMERS_BASKET." SET customers_basket_quantity = '".$quantity."' WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."'");

		if(is_array($attributes)) {
			reset($attributes);
			while(list ($option, $value) = each($attributes)) {
				$this->contents[$products_id]['attributes'][$option] = $value;
				if(isset($_SESSION['customer_id']))
					$db->db_query("UPDATE ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." SET products_options_value_id = '".$value."' WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."' AND products_options_id = '".$option."'");
			}
		}
	}

	public function cleanup() {
		global $db;
		reset($this->contents);
		while(list ($key,) = each($this->contents)) {
			if($this->contents[$key]['qty'] < 1) {
				unset($this->contents[$key]);
				if(isset($_SESSION['customer_id'])) {
					$db->db_query("DELETE FROM ".TABLE_CUSTOMERS_BASKET." WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$key."'");
					$db->db_query("DELETE FROM ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$key."'");
				}
			}
		}
	}

	public function count_contents() {
		$total_items = 0;
		if(is_array($this->contents)) {
			reset($this->contents);
			while(list($products_id,) = each($this->contents))
				$total_items += $this->get_quantity($products_id);
		}
		return $total_items;
	}

	public function get_quantity($products_id) {
		if(isset($this->contents[$products_id]))
			return $this->contents[$products_id]['qty'];
		else
			return 0;
	}

	public function in_cart($products_id) {
		if(isset($this->contents[$products_id]))
			return true;
		else
			return false;
	}

	public function remove($products_id) {
		global $db;
		if (isset($this->contents[$products_id])) {
		  $this->contents[$products_id] = NULL;
		}

		if(isset($_SESSION['customer_id'])) {
			$db->db_query("DELETE FROM ".TABLE_CUSTOMERS_BASKET." WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."'");
			$db->db_query("DELETE FROM ".TABLE_CUSTOMERS_BASKET_ATTRIBUTES." WHERE customers_id = '".$_SESSION['customer_id']."' AND products_id = '".$products_id."'");
		}
		$this->cartID = $this->generate_cart_id();
	}

	public function remove_all() {
		$this->reset();
	}

	public function get_product_id_list() {
		$product_id_list = '';
		if (is_array($this->contents)) {
			reset($this->contents);
			while (list ($products_id,) = each($this->contents))
				$product_id_list .= ', '.$products_id;
		}
		return substr($product_id_list, 2);
	}

    public function calculate() {
    	global $price, $db;
	    $this->total = 0;
	    $this->weight = 0;
	    $this->tax = array ();
	    $this->total_discount = array ();
	    if (!is_array($this->contents))
	    	return 0;
	    reset($this->contents);
  		$products = $this->get_products();

      foreach ($this->contents as $products_id => $products_value) {
        $qty = $this->contents[$products_id]['qty'];
        $product = $db->db_query("SELECT
        								products_id,
        								products_price,
        								products_discount_allowed,
        								products_tax_class_id,
        								products_weight
        							FROM
        								".TABLE_PRODUCTS."
        							WHERE
        								products_id='".get_prid($products_id)."'");
        if($product->_numOfRows) {
          if(($_price = $price->GetGroupPrice($product->fields['products_id'], $qty)) && ($_SESSION['customers_status']['customers_status_graduated_prices'] == 1))
            $single_q = $qty;
          else
            $single_q = 1;

				$products_price = $price->GetPrice($product->fields['products_id'], false, $single_q, $product->fields['products_tax_class_id'], $product->fields['products_price']);
				$this->total += $products_price * $qty;
          $this->weight += ($qty * $product->fields['products_weight']);
          $attribute_price = 0;
          if(isset($this->contents[$products_id]['attributes'])) {
            reset($this->contents[$products_id]['attributes']);
            while(list($option, $value) = each($this->contents[$products_id]['attributes'])) {
              $values = $price->GetOptionPrice($product->fields['products_id'], $option, $value);
              $this->weight 		+= $values['weight'] * $qty;
              $this->total 		+= $values['price'] * $qty;
              $attribute_price 	+= $values['price'];
            }
          }
          
				if($product->fields['products_tax_class_id'] != 0) {
					if ($_SESSION['customers_status']['customers_status_ot_discount_flag'] == 1) {
						$products_price_tax = $products_price - ($products_price / 100 * $_SESSION['customers_status']['customers_status_ot_discount']);
						$attribute_price_tax = $attribute_price - ($attribute_price / 100 * $_SESSION['customers_status']['customers_status_ot_discount']);
					}
					$products_tax = $price->TAX[$product->fields['products_tax_class_id']];
					$products_tax_description = get_tax_description($product->fields['products_tax_class_id']);

					// Preis inkl. MwSt.
					if ($_SESSION['customers_status']['customers_status_show_price_tax'] == '1') {
						if ($_SESSION['customers_status']['customers_status_ot_discount_flag'] == 1) {
							$this->tax[$product->fields['products_tax_class_id']]['value'] += ((($products_price_tax+$attribute_price_tax) / (100 + $products_tax)) * $products_tax)*$qty;
							$this->tax[$product->fields['products_tax_class_id']]['desc'] = TAX_ADD_TAX."$products_tax_description";
						} else {
							$this->tax[$product->fields['products_tax_class_id']]['value'] += ((($products_price+$attribute_price) / (100 + $products_tax)) * $products_tax)*$qty;
							$this->tax[$product->fields['products_tax_class_id']]['desc'] = TAX_ADD_TAX."$products_tax_description";
						}
					}
					// Preis exkl. MwSt. + tax at checkout
					if ($_SESSION['customers_status']['customers_status_show_price_tax'] == 0 && $_SESSION['customers_status']['customers_status_add_tax_ot'] == 1) {
						if ($_SESSION['customers_status']['customers_status_ot_discount_flag'] == 1) {
							$this->tax[$product->fields['products_tax_class_id']]['value'] += (($products_price_tax+$attribute_price_tax) / 100) * ($products_tax)*$qty;
							$this->total_discount[$product->fields['products_tax_class_id']]+=(($products_price_tax+$attribute_price_tax) / 100) * ($products_tax)*$qty;
							$this->tax[$product->fields['products_tax_class_id']]['desc'] = TAX_NO_TAX."$products_tax_description";
						} else {
							$this->tax[$product->fields['products_tax_class_id']]['value'] += (($products_price+$attribute_price) / 100) * ($products_tax)*$qty;
							$this->total_discount[$product->fields['products_tax_class_id']]+=(($products_price+$attribute_price) / 100) * ($products_tax)*$qty;
							$this->tax[$product->fields['products_tax_class_id']]['desc'] = TAX_NO_TAX."$products_tax_description";
						}
					}
				}
			}
		}
		foreach ($this->total_discount as $value) {
	      $this->total+=round($value, $price->get_decimal_places($order->info['currency']));
    }
	}

	public function attributes_price($products_id) {
		global $price;
		if(isset($this->contents[$products_id]['attributes'])) {
			reset($this->contents[$products_id]['attributes']);
			while(list($option, $value) = each($this->contents[$products_id]['attributes'])) {
				$values = $price->GetOptionPrice($products_id, $option, $value);
				$attributes_price += $values['price'];
			}
		}
		return $attributes_price;
	}

	public function get_products() {
		global $price, $main, $db;
		if (!is_array($this->contents))
			return false;
    
    $products_bak = $this->products; 
		if(is_object($product))	
      global $product;
		else 
      $product = new product();
		
		$products_array = array();
		reset($this->contents);

		while(list($products_id,) = each($this->contents)) {
			if(isset($this->contents[$products_id]['qty']) 
          && $this->contents[$products_id]['qty'] != 0 
          && $this->contents[$products_id]['qty'] !=''){
          
        if (
            ($product_item = array_get_item($products_bak, 'id', $products_id)) !== false
            && $product_item['quantity'] == $this->contents[$products_id]['qty'] ){
          
          $products_array[] = $product_item;
        }
        else {
//        print_r($products_bak);
//        die($products_id);
  				$img = '';
  				$products = $db->db_query("SELECT
  												p.products_id,
  												pd.products_name,
  												pd.products_description,
  												pd.products_short_description,
  												p.products_shippingtime,
  												p.products_image,
  												p.products_model,
  												p.products_price,
  												p.products_discount_allowed,
  												p.products_weight,
  												p.products_tax_class_id
  											FROM
  												".TABLE_PRODUCTS." p,
  												".TABLE_PRODUCTS_DESCRIPTION." pd
  											WHERE
  												p.products_id = '".get_prid($products_id)."'
  											AND
  												pd.products_id = p.products_id
  											AND
  												pd.language_id = '".$_SESSION['languages_id']."'");
  
  				if($products->_numOfRows) {
  					$prid = $products->fields['products_id'];
  
  					$products_price = $price->GetPrice($products->fields['products_id'], false, ($price->GetGroupPrice($products_id, $this->contents[$products_id]['qty']) ? $this->contents[$products_id]['qty'] : 1), $products->fields['products_tax_class_id']);
					
  					$desc = (CHECKOUT_PRODUCT_DETAIL == 'short' ? $products->fields['products_short_description'] : (CHECKOUT_PRODUCT_DETAIL == 'long' ? $products->fields['products_description'] : ''));
					
  					$products_array[] = array(	'id' => $products_id,
  												'name' => $products->fields['products_name'],
  												'desc' => $desc,
  												'model' => $products->fields['products_model'],
  												'image' => $product->productImage($products->fields['products_image'], 'icon'),
												'price' => $products_price + $this->attributes_price($products_id),
												'single_price' => $products_price,
  												'quantity' => $this->contents[$products_id]['qty'],
  												'weight' => $products->fields['products_weight'],
  												'shipping_time' => $main->getShippingStatusName($products->fields['products_shippingtime']),
												'final_price' => ($products_price + $this->attributes_price($products_id)),
  												'tax_class_id' => $products->fields['products_tax_class_id'],
  												'attributes' => $this->contents[$products_id]['attributes']);
  				}
  			}
			}
		}
    	$this->products = $products_array;
		return $products_array;
	}

	public function show_total() {
		$this->calculate();

		return $this->total;
	}

	public function show_weight() {
		$this->calculate();

		return round($this->weight, 2);
	}

	public function show_tax($format = true) {
		global $price;
		$this->calculate();
		$output = "";
		$val = 0;
        $gval = 0;

		foreach($this->tax as $key => $value) {
			if ($this->tax[$key]['value'] > 0 ) {
				$output .= $this->tax[$key]['desc'].": ".$price->format($this->tax[$key]['value'], true).'<br />';
        $gval+=$this->tax[$key]['value'];
			}
		}
		if($format)
			return $output;
		else
			return $gval;
	}

	public function generate_cart_id($length = 5) {
		return create_random_value($length, 'digits');
	}

	public function get_content_type() {
		global $db;

		$this->content_type = false;

		if((DOWNLOAD_ENABLED == 'true') && ($this->count_contents() > 0)) {
			reset($this->contents);
			while(list($products_id,) = each($this->contents)) {
				if(isset($this->contents[$products_id]['attributes'])) {
					reset($this->contents[$products_id]['attributes']);
					while(list(, $value) = each($this->contents[$products_id]['attributes'])) {

						$virtual = $db->db_query("SELECT
														COUNT(*) AS total
													FROM
														".TABLE_PRODUCTS_ATTRIBUTES." pa,
														".TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD." pad
													WHERE
														pa.products_id = '".$products_id."'
													AND
														pa.options_values_id = '".$value."'
													AND
														pa.products_attributes_id = pad.products_attributes_id");

						if($virtual->fields['total'] > 0) {
							switch ($this->content_type) {
								case 'physical' :
									$this->content_type = 'mixed';
									return $this->content_type;
									break;

								default :
									#$this->content_type = 'virtual';
									$this->content_type = 'mixed';
									break;
							}
						} else {
							switch ($this->content_type) {
								case 'virtual' :
									$this->content_type = 'mixed';
									return $this->content_type;
									break;

								default :
									$this->content_type = 'physical';
									break;
							}
						}
					}
				} else {
					switch ($this->content_type) {
						case 'virtual' :
							$this->content_type = 'mixed';
							return $this->content_type;
							break;

						default :
							$this->content_type = 'physical';
							break;
					}
				}
			}
		} else {
			$this->content_type = 'physical';
		}
		return $this->content_type;
	}

	public function unserialize($broken) {
		for (reset($broken); $kv = each($broken);) {
			$key = $kv['key'];
			if (gettype($this-> $key) != "user function")
				$this-> $key = $kv['value'];
		}
	}

	// GV Code Start
	// ------------------------ ICW CREDIT CLASS Gift Voucher Addittion-------------------------------Start
	// amend count_contents to show nil contents for shipping
	// as we don't want to quote for 'virtual' item
	// GLOBAL CONSTANTS if NO_COUNT_ZERO_WEIGHT is true then we don't count any product with a weight
	// which is less than or equal to MINIMUM_WEIGHT
	// otherwise we just don't count gift certificates

	public function count_contents_virtual() { // get total number of items in cart disregard gift vouchers
		global $db;

		$total_items = 0;
		if(is_array($this->contents)) {
			reset($this->contents);
			while(list($products_id,) = each($this->contents)) {
				$no_count = false;
				$gv_result = $db->db_query("SELECT products_model FROM ".TABLE_PRODUCTS." WHERE products_id = '".$products_id."'");
				if(preg_match('/^GIFT/', $gv_result->fields['products_model']))
					$no_count = true;

				if(NO_COUNT_ZERO_WEIGHT == 1) {
					$gv_result = $db->db_query("SELECT products_weight FROM ".TABLE_PRODUCTS." WHERE products_id = '".get_prid($products_id)."'");
					if($gv_result->fields['products_weight'] <= MINIMUM_WEIGHT)
						$no_count = true;
				}
				if(!$no_count)
					$total_items += $this->get_quantity($products_id);
			}
		}
		return $total_items;
	}
}